﻿using EasyCaching.Core;
using Library.Common.Encrypt;
using Library.Common.Serialize;
using Library.Core.Application.BaseAction;
using Library.Core.Application.IInfrastructure;
using Synthesize.Common.Domain.Aggregation.Dtos;
using Synthesize.Common.Domain.Event;
using Synthesize.Common.ServiceInterface.UseCase;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Synthesize.Common.Application.UseCase
{
    /// <summary>
    /// 接口安全逻辑
    /// </summary>
    public class SafeServicecs : BaseService, ISafeService
    {

        private readonly IRedisCachingProvider _redisCaching;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="container"></param>
        /// <param name="redisCaching"></param>
        public SafeServicecs(IIocContainer container
            , IRedisCachingProvider redisCaching
            ) : base(container)
        {
            _redisCaching = redisCaching;
        }

        /// <summary>
        /// 获取对应IP+时间戳的记录
        /// </summary>
        /// <param name="requestIp"></param>
        /// <param name="timestamp"></param>
        /// <returns></returns>
        public async Task<bool> JudgeReplayAttack(string requestIp,string timestamp)
        {
            var result = false;
            var timestampStr = await _redisCaching.StringGetAsync(RedisLogInfo.RedisApiTimestampId + SecurityHelper.GetMD5Hash(requestIp + timestamp));
            if (string.IsNullOrEmpty(timestampStr))
            {
                await _redisCaching.StringSetAsync(RedisLogInfo.RedisApiTimestampId + SecurityHelper.GetMD5Hash(requestIp + timestamp), timestamp,TimeSpan.FromSeconds(RedisLogInfo.RedisApiTimestampTimeout));
            }
            else {
                result = true;
            }
            return result;
        }

        /// <summary>
        /// 插入接口访问监控日志
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> SaveApiMonitorLog(SafeApiMonitorLogEvent input)
        {
            var result = await _redisCaching.HSetAsync(RedisLogInfo.RedisApiMonitorHashId, input.Id,JsonHelper.ToJson(input));
            return result;
        }

        /// <summary>
        /// 删除过期接口访问记录信息
        /// </summary>
        public async Task RemoveExpiredApiMonitorLog()
        {
            var apiMonitorList = await _redisCaching.HGetAllAsync(RedisLogInfo.RedisApiMonitorHashId);
            if (apiMonitorList.Count > 0)
            {
                DateTime nowTime = DateTime.Now;
                var safeApiMonitorLogList = new List<SafeApiMonitorLogEvent>();
                foreach (var item in apiMonitorList)
                {
                    var apiMonitorLog = JsonHelper.JsonToObject<SafeApiMonitorLogEvent>(item.Value);
                    if (apiMonitorLog!=null)
                    {
                        safeApiMonitorLogList.Add(apiMonitorLog);
                    }
                }
                var keys = safeApiMonitorLogList.Where(p => p.RequestTime.AddSeconds(RedisLogInfo.RedisApiMonitorTimeOut) <= nowTime).Select(p => p.Id).ToList();
                if (keys.Count > 0)
                {
                   await _redisCaching.HDelAsync(RedisLogInfo.RedisApiMonitorHashId, keys);
                }
            }
        }

        /// <summary>
        /// 插入接口访问次数
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> IncrementApiMonitorNumber(SafeApiMonitorLogEvent input)
        {
            var result = false;
            var apiMonitorNumber = await _redisCaching.HIncrByAsync(RedisLogInfo.RedisApiMonitorNumberHashId, input.RequestPath,1);
            if (apiMonitorNumber>0)
            {
                result = true;
            }
            return result;
        }
    }
}
